﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2010-08-26 16:31:32Z</CreationDate>
</File>
*/
#endregion

using System;
using System.Security;

namespace Outcoder
{
	/// <summary>
	/// A generic <see cref="WeakReference"/>, which references an object 
	/// while still allowing that object to be reclaimed by garbage collection.   
	/// </summary>   
	/// <typeparam name="T">The type of the object that is referenced.</typeparam>   
	[Serializable]
	public class WeakReference<T> where T : class
	{
		readonly WeakReference weakReference;

#if SILVERLIGHT || WINDOWSPHONE
		[SecuritySafeCritical]
		protected WeakReference()
		{
			/* Intentionally left blank. */
		}
#endif

		/// <summary>
		/// Initializes a new instance of the <see cref="WeakReference&lt;T&gt;"/> class.
		/// </summary>
		/// <param name="target">The target.</param>
		public WeakReference(T target)// : base(target)
		{
			weakReference = new WeakReference(target);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="WeakReference&lt;T&gt;"/> class.
		/// </summary>
		/// <param name="target">The target.</param>
		/// <param name="trackResurrection">if set to <c>true</c> [track resurrection].</param>
		public WeakReference(T target, bool trackResurrection)
			//: base(target, trackResurrection)
		{
			weakReference = new WeakReference(target, trackResurrection);
		}

		/// <summary>
		/// Gets or sets the object (the target) referenced by the current 
		/// <see cref="T:System.WeakReference"/> object.
		/// </summary>
		/// <value></value>
		/// <returns>null if the object referenced by the current 
		/// <see cref="T:System.WeakReference"/> object has been garbage collected; 
		/// otherwise, a reference to the object referenced by the current 
		/// <see cref="T:System.WeakReference"/> object.
		/// </returns>
		/// <exception cref="T:System.InvalidOperationException">
		/// The reference to the target object is invalid. 
		/// This exception can be thrown while setting this property 
		/// if the value is a null reference or if the object 
		/// has been finalized during the set operation.
		/// </exception>
		public T Target
		{
			get
			{
				return (T)weakReference.Target;
			}
			set
			{
				weakReference.Target = value;
			}
		}

		/// <summary>
		/// Performs an implicit conversion 
		/// from <see cref="WeakReference{T}"/> 
		/// to <see cref="T"/>.
		/// </summary>
		/// <param name="reference">The reference.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator T(WeakReference<T> reference)
		{
			return reference != null ? reference.Target : null;
		}

		/// <summary>
		/// Performs an implicit conversion from <see cref="T"/> 
		/// to <see cref="WeakReference{T}"/>.
		/// </summary>
		/// <param name="target">The target.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator WeakReference<T>(T target)
		{
			ArgumentValidator.AssertNotNull(target, "target");
			return new WeakReference<T>(target);
		}
	}
}
